﻿using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Windows;
using BestCode.Creds.View.Model;
using BestCode.Creds.View.Utils;
using Didsoft.Wpf.ViewModel;

namespace BestCode.Creds.View.ViewModel
{
    public class VmPersonalData : BindableObject
    {
        #region viewmodel actions

        //private CREDSEntities dbContext = null;

        private ObservableCollection<Dato> students;
        public ObservableCollection<Dato> Students
        {
            get { return students; }
            set { students = value;
                if(students!=null)
                    StudentsCount = students.Count;
                this.FirePropertyChanged("Students"); }
        }

        private int studentsCount;
        public int StudentsCount
        {
            get { return studentsCount; }
            set
            {
                studentsCount = value;
                this.FirePropertyChanged("StudentsCount");
            }

        }

        private bool isPrimaryTemplate;
        public bool IsPrimaryTemplate
        {
            get { return isPrimaryTemplate; }
            set { isPrimaryTemplate = value;
                LoadCourses();
                this.FirePropertyChanged("IsPrimaryTemplate"); }
        }



        private ObservableCollection<string> courses;
        public ObservableCollection<string> Courses
        {
            get { return courses; }
            set { courses = value; this.FirePropertyChanged("Courses"); }
        }

        private string selectedCourse;
        public string SelectedCourse
        {
            get { return selectedCourse; }
            set
            {
                selectedCourse = value;this.FirePropertyChanged("SelectedCourse");
                LoadStudentsFromSelectedCourse();

            }
        }

        private string outputFolder;
        public string OutputFolder
        {
            get { return outputFolder; }
            set
            {
                outputFolder = value; this.FirePropertyChanged("OutputFolder");

            }
        }

        private string picturesFolder;
        public string PicturesFolder
        {
            get { return picturesFolder; }
            set
            {
                picturesFolder = value; this.FirePropertyChanged("PicturesFolder");

            }
        }

        private string strMessagePrintConfirm;
        public string StrMessagePrintConfirm
        {
            get { return strMessagePrintConfirm; }
            set
            {
                strMessagePrintConfirm = value;
            }
        }

        public ObservableCollection<Dato> EnabledItems
        {
            get
            {
                return new ObservableCollection<Dato>(Students.Where(p => p.Habilitado));
            }
        }



        private void LoadStudentsFromSelectedCourse()
        {
            var st = DataFactory.Current.DBContext.Datos.Where(p => p.Curso.Equals(SelectedCourse)).OrderBy(p=> p.ApellidoPaterno).ThenBy(p=>p.ApellidoMaterno);
            Students = new ObservableCollection<Dato>(st);
        }

        public VmPersonalData()
        {
            OutputFolder = ConfigReader.Current.Config.DefaultOutputFolder;
            PicturesFolder = ConfigReader.Current.Config.DefaultPicturesFolder;
            //dbContext = new CREDSEntities();
            LoadCourses();
            
        }

        private void LoadCourses()
        {
            if (IsPrimaryTemplate)
            {
                var datas = DataFactory.Current.DBContext.Datos.Where(p => p.Curso.Contains("P") || p.Curso.Contains("AA") || p.Curso.Contains("AB")).Select(p => p.Curso).Distinct();
                Courses = new ObservableCollection<string>(datas);
            }
            else
            {
                var datas = DataFactory.Current.DBContext.Datos.Where(p => p.Curso.Contains("S")).Select(p => p.Curso).Distinct();
                Courses = new ObservableCollection<string>(datas);
            }
            
        }

        #endregion

        #region generator

        public void GenerateCredentialsSecundary()
        {
            //use this for Secundaria level
            string credencialImage = ConfigReader.Current.Config.AnverseCredentialPath;
            
            var a = new DirectoryInfo(OutputFolder);
            var coursefolder = a.CreateSubdirectory(SelectedCourse);

            try
            {
                foreach (var person in EnabledItems)
                {
                    var picture = PicturesFolder +"\\"+ person.Foto + ".jpg";

                    System.Drawing.Image canvas = Bitmap.FromFile(credencialImage);
                    Graphics gra = Graphics.FromImage(canvas);
                    Bitmap smallImg = new Bitmap(picture);
                    
                    
                    var res = resizeImage(smallImg, new System.Drawing.Size() { Height = 372, Width = 310 });
                    gra.DrawImage(res, new System.Drawing.Point(780, 202));


                    gra.DrawString(person.Nombres, new Font("Lao UI", 38, System.Drawing.FontStyle.Bold), SystemBrushes.WindowText, new System.Drawing.Point(80, 280));
                    gra.DrawString(person.ApellidoPaterno + " " + person.ApellidoMaterno, new Font("Lao UI", 36, System.Drawing.FontStyle.Bold), SystemBrushes.WindowText, new System.Drawing.Point(80, 335));
                    
                    gra.DrawString("Cod-"+person.Codigo.ToString(), new Font("Lao UI", 36, System.Drawing.FontStyle.Bold), Brushes.White, new System.Drawing.Point(765, 590));


                    //verify if the full address is very large
                    string fullAddress = person.Calle +
                                         (person.NumDireccion != null
                                             ? " #" + person.NumDireccion.ToString()
                                             : string.Empty) + " " + person.Zona.ToUpper();

                    if (fullAddress.Length > 35)
                    {
                        fullAddress = person.Calle +
                                      (person.NumDireccion != null
                                      ? " #" + person.NumDireccion.ToString():string.Empty);
                        gra.DrawString(fullAddress, new Font("Lao UI", 25, System.Drawing.FontStyle.Bold), Brushes.Black, new System.Drawing.Point(88, 465));
                        gra.DrawString(person.Zona.ToUpper(), new Font("Lao UI", 25, System.Drawing.FontStyle.Bold), Brushes.Black, new System.Drawing.Point(88, 500));
                        gra.DrawString("Telef. "+person.Telfdomicilio , new Font("Lao UI", 25, System.Drawing.FontStyle.Regular), Brushes.Black, new System.Drawing.Point(88, 550));
                    }
                    else
                    {
                        gra.DrawString(fullAddress, new Font("Lao UI", 25, System.Drawing.FontStyle.Bold), Brushes.Black, new System.Drawing.Point(88, 465));
                        gra.DrawString("Telef. "+person.Telfdomicilio , new Font("Lao UI", 25, System.Drawing.FontStyle.Regular), Brushes.Black, new System.Drawing.Point(88, 510));
                    }
                    

                    canvas.Save(coursefolder.ToString() + "\\" + person.Foto + ".png", System.Drawing.Imaging.ImageFormat.Png);
                    canvas.Dispose();
                    gra.Dispose();
                    smallImg.Dispose();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }


        public void GenerateCredentialsPrimary()
        {
            //use this for Primaria level
            string credencialImage = ConfigReader.Current.Config.AnverseCredentialPath;


            var a = new DirectoryInfo(OutputFolder);
            var coursefolder = a.CreateSubdirectory(SelectedCourse);

            var f = coursefolder.ToString();


            try
            {
                foreach (var person in EnabledItems)
                {
                    var picture = PicturesFolder + "\\" + person.Foto + ".jpg";

                    System.Drawing.Image canvas = Bitmap.FromFile(credencialImage);
                    Graphics gra = Graphics.FromImage(canvas);
                    Bitmap smallImg = new Bitmap(picture);


                    #region crop image only for Primaria level

                    //var croppedBitmap = smallImg.Clone(
                    //                                    new Rectangle(0, 0, smallImg.Width, smallImg.Height - 45),
                    //                                    PixelFormat.DontCare);

                    var croppedBitmap = smallImg.Clone(
                                                        new Rectangle(0, 10, smallImg.Width, smallImg.Height - 45),
                                                        PixelFormat.Format64bppArgb);

                    var res = resizeImage(croppedBitmap, new System.Drawing.Size() { Height = 343, Width = 310 });
                    gra.DrawImage(res, new System.Drawing.Point(780, 216));


                    #endregion


                    gra.DrawString(person.Nombres, new Font("Lao UI", 38, System.Drawing.FontStyle.Bold), SystemBrushes.WindowText, new System.Drawing.Point(80, 280));
                    gra.DrawString(person.ApellidoPaterno + " " + person.ApellidoMaterno, new Font("Lao UI", 38, System.Drawing.FontStyle.Bold), SystemBrushes.WindowText, new System.Drawing.Point(80, 335));

                    gra.DrawString("Cod-" + person.Codigo.ToString(), new Font("Lao UI", 36, System.Drawing.FontStyle.Bold), Brushes.White, new System.Drawing.Point(760, 583));


                    //verify if the full address is very large
                    string fullAddress = person.Calle +
                                         (person.NumDireccion != null
                                             ? " #" + person.NumDireccion.ToString()
                                             : string.Empty) + " " + person.Zona.ToUpper();

                    if (fullAddress.Length > 35)
                    {
                        fullAddress = person.Calle +
                                      (person.NumDireccion != null
                                      ? " #" + person.NumDireccion.ToString() : string.Empty);
                        gra.DrawString(fullAddress, new Font("Lao UI", 25, System.Drawing.FontStyle.Bold), Brushes.Black, new System.Drawing.Point(88, 465));
                        gra.DrawString(person.Zona.ToUpper(), new Font("Lao UI", 25, System.Drawing.FontStyle.Bold), Brushes.Black, new System.Drawing.Point(88, 500));
                        gra.DrawString("Telef. " + person.Telfdomicilio, new Font("Lao UI", 25, System.Drawing.FontStyle.Regular), Brushes.Black, new System.Drawing.Point(88, 550));
                    }
                    else
                    {
                        gra.DrawString(fullAddress, new Font("Lao UI", 25, System.Drawing.FontStyle.Bold), Brushes.Black, new System.Drawing.Point(88, 465));
                        gra.DrawString("Telef. " + person.Telfdomicilio, new Font("Lao UI", 25, System.Drawing.FontStyle.Regular), Brushes.Black, new System.Drawing.Point(88, 510));
                    }


                    canvas.Save(coursefolder.ToString() + "\\" + person.Foto + ".png", System.Drawing.Imaging.ImageFormat.Png);
                    canvas.Dispose();
                    gra.Dispose();
                    smallImg.Dispose();
                }


            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        
        public void GenerateCredentialsReverse()
        {
            string credencialImage = ConfigReader.Current.Config.ReverseCredentialPath;

            var a = new DirectoryInfo(OutputFolder);
            var coursefolder = a.CreateSubdirectory(SelectedCourse+"_Reverso");

            var f = coursefolder.ToString();


            try
            {
                foreach (var person in EnabledItems)
                {
                    var picture = PicturesFolder + "\\" + person.Foto + ".jpg";

                    System.Drawing.Image canvas = Bitmap.FromFile(credencialImage);
                    Graphics gra = Graphics.FromImage(canvas);


                    var image =
                        Didsoft.Utils.CodeBars.Common.GenerateQRCode(person.ApellidoPaterno + " " +
                                                                     person.ApellidoMaterno + " " + person.Nombres +" | cod-"+person.Codigo, ImageFormat.Png);

                    //gra.DrawImage(resizeImage(ByteArrayToImage(image), new System.Drawing.Size() {Height = 200, Width = 200}), new System.Drawing.Point(800, 450));
                    gra.DrawImage(ByteArrayToImage(image), new System.Drawing.Point(800, 430));
                    gra.DrawString(person.Codigo.ToString(), new Font("Lao UI", 12, System.Drawing.FontStyle.Bold), Brushes.White, new System.Drawing.Point(20, 20));
                

                    canvas.Save(coursefolder.ToString() + "\\" + person.Foto + ".png", System.Drawing.Imaging.ImageFormat.Png);
                    canvas.Dispose();
                    gra.Dispose();
                   
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        
        public static System.Drawing.Image resizeImage(System.Drawing.Image imgToResize, System.Drawing.Size size)
        {
            return (System.Drawing.Image)(new Bitmap(imgToResize, size));
        }

        public Image ByteArrayToImage(byte[] byteArrayIn)
        {
            MemoryStream ms = new MemoryStream(byteArrayIn);
            Image returnImage = Image.FromStream(ms);
            return returnImage;
        }

        #endregion


        internal void SearchByFilter(string filter)
        {
            Students =
                new ObservableCollection<Dato>(DataFactory.Current.DBContext.Datos.Where(p =>
                                                            p.Curso.Equals(SelectedCourse) && 
                                                           (p.ApellidoPaterno.Contains(filter) || p.ApellidoMaterno.Contains(filter) || p.Nombres.Contains(filter))).OrderBy(p=>p.ApellidoPaterno).ThenBy(p=>p.ApellidoMaterno)  );
        }


        public void SendToPrinter()
        {
            var printer = new RawPrinterHelper();
            var a = new DirectoryInfo(OutputFolder);
            var coursefolder = a.CreateSubdirectory(SelectedCourse);
            

            foreach (var item in EnabledItems)
            {
                RawPrinterHelper.SendFileToPrinter(ConfigReader.Current.Config.DefaultPrinterName,
                    coursefolder.ToString() + "\\" + item.Foto + ".png");
            }


            //ProcessStartInfo info = new ProcessStartInfo();
            //info.Verb = "print";
            //info.FileName = @"c:\output.pdf";
            //info.CreateNoWindow = true;
            //info.WindowStyle = ProcessWindowStyle.Hidden;

            //Process p = new Process();
            //p.StartInfo = info;
            //p.Start();

            //p.WaitForInputIdle();
            //System.Threading.Thread.Sleep(3000);
            //if (false == p.CloseMainWindow())
            //    p.Kill();
        }

    }
}
